package cn.anlucky.apiadmin.service.impl;

import cn.anlucky.apiadmin.dto.PageDto;
import cn.anlucky.apiadmin.enums.RequestBodyTypeEnums;
import cn.anlucky.apiadmin.pojo.CustomException;
import cn.anlucky.apiadmin.utils.RedisUtil;
import cn.anlucky.apiadmin.vo.ApiInfoListVo;
import cn.anlucky.apiadmin.vo.ApiInfoVo;
import cn.anlucky.apiadmin.vo.R;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.anlucky.apiadmin.pojo.Apiinfo;
import cn.anlucky.apiadmin.service.ApiinfoService;
import cn.anlucky.apiadmin.mapper.ApiinfoMapper;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
* @author 95135
* @description 针对表【apiinfo】的数据库操作Service实现
* @createDate 2024-04-23 10:58:43
*/
@Service
public class ApiinfoServiceImpl extends ServiceImpl<ApiinfoMapper, Apiinfo>
    implements ApiinfoService{

    @Autowired
    private RedisUtil redisUtil;


    /**
     * 前台获取所有API列表
     *
     * @return
     */
    @Override
    public R getApiInfoList() {

        /**
         * Redis存储API调用get 去除当前API的调用次数对象
         * redisUtil.set(当前对象ID + #todayCallNumber,今日请求次数,DateTimeUtil.getTommorrowTime()) // 今日调用次数，明日自动过期
         * redisUtil.set(当前对象ID + #totalCallNumber,总共的调用次数) // 今日调用次数 永不过期
         */

        // 只取启用的
        LambdaQueryWrapper<Apiinfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Apiinfo::getEnabled,1);

        List<Apiinfo> list = baseMapper.selectList(wrapper);

        // 返回大对象
        ApiInfoListVo apiInfoListVo = new ApiInfoListVo();

        // 单独API的对象信息
        List<ApiInfoVo> apiInfoVoList = new ArrayList<>();

        // 总请求次数
        Long total = 0l;
        // 今日请求次数
        Long todayTotal = 0l;

        for (int i = 0; i < list.size(); i++) {
            // 取当前循环对象
            Apiinfo apiinfo = list.get(i);

            // 取缓存中当前API的今日调用次数数据
            Long todayCallNumber = Long.valueOf(redisUtil.get(apiinfo.getId()+"#todayCallNumber")==null?"0":redisUtil.get(apiinfo.getId()+"#todayCallNumber").toString());
            // 取缓存中当前API的总共的调用次数
            Long totalCallNumber = Long.valueOf(redisUtil.get(apiinfo.getId()+"#totalCallNumber")==null?"0":redisUtil.get(apiinfo.getId()+"#totalCallNumber").toString());

            total = total + totalCallNumber; // 一共调用次数相加
            todayTotal = todayTotal + todayCallNumber; // 今日调用次数相加

            ApiInfoVo apiInfoVo = new ApiInfoVo(Long.valueOf(apiinfo.getId()),apiinfo.getTitle(),apiinfo.getDescription(),totalCallNumber,todayCallNumber);
            apiInfoVoList.add(apiInfoVo);

        }
        apiInfoListVo.setSize(Long.valueOf(list.size()));
        apiInfoListVo.setList(apiInfoVoList);
        apiInfoListVo.setTotalTodayCallNumber(todayTotal);
        apiInfoListVo.setTotalCallNumber(total);

        return R.success(apiInfoListVo);
    }

    /**
     * 增加一条API
     *
     * @param map
     * @return
     */
    @Override
    public R insertApiInfo(Map<String, Object> map) {
        // dateForm = {id=null, title=取说说, url=https://api.oioweb.cn/api/qq/MsgList, description=取说说, method=GET, responseFormart=JSON, requestBody=null, requestBodyType=ParamsSubmit, responseDemo=null, headers=[], subParams=[{paramsName=qq, paramsValue=951359056, paramsType=String, paramsDESC=qq}, {paramsName=page, paramsValue=1, paramsType=String, paramsDESC=页码}]}
        if (Objects.isNull(map)){
            throw new CustomException("取到数据为空，添加失败");
        }

        String title = map.get("title")==null?null:map.get("title").toString();
        String url = map.get("url")==null?null:map.get("url").toString();
        String description = map.get("description")==null?null:map.get("description").toString();
        String method = map.get("method")==null?null:map.get("method").toString();
        String responseFormart = map.get("responseFormart")==null?null:map.get("responseFormart").toString();
        String requestBodyType = map.get("requestBodyType")==null?null:map.get("requestBodyType").toString();
        String headers = map.get("headers")==null?null:map.get("headers").toString();
        String responseDemo = map.get("responseDemo")==null?null:map.get("responseDemo").toString();

        if (Strings.isBlank(title)){
            throw new CustomException("API名称不能为空！");
        }

        if (Strings.isBlank(url)){
            throw new CustomException("请求链接不能为空！");
        }

        if (Strings.isBlank(description)){
            throw new CustomException("API介绍不能为空！");
        }
        if (Strings.isBlank(method)){
            throw new CustomException("请求方式不能为空！");
        }
        if (Strings.isBlank(responseFormart)){
            throw new CustomException("响应格式不能为空！");
        }

        if (Strings.isBlank(requestBodyType)){
            throw new CustomException("提交内容类型不能为空！");
        }


        Apiinfo apiinfo = new Apiinfo();
        apiinfo.setTitle(title);
        apiinfo.setUrl(url);
        apiinfo.setDescription(description);
        apiinfo.setMethod(method);
        apiinfo.setResponseFormart(responseFormart);
        apiinfo.setRequestBodyType(requestBodyType);

        if (RequestBodyTypeEnums.ParamsSubmit.getCode().equals(requestBodyType)){
            apiinfo.setRequestParams(map.get("subParams")==null?null:map.get("subParams").toString());
        }
        if (RequestBodyTypeEnums.JsonSubmit.getCode().equals(requestBodyType)){
            apiinfo.setRequestParams(map.get("requestBody")==null?null:map.get("requestBody").toString());
        }
        apiinfo.setRequestHeads(headers);
        apiinfo.setResponseDemo(responseDemo);
        apiinfo.setEnabled("1"); // 启用

        int insert = baseMapper.insert(apiinfo);

        if (insert > 0){
            return R.success("添加API["+title+"]成功");
        }
        throw new CustomException("添加失败，请联系管理员");
    }

    /**
     * 修改一个API
     *
     * @param map
     * @return
     */
    @Override
    public R updateApiInfoById(Map<String, Object> map) {
        // dateForm = {id=null, title=取说说, url=https://api.oioweb.cn/api/qq/MsgList, description=取说说, method=GET, responseFormart=JSON, requestBody=null, requestBodyType=ParamsSubmit, responseDemo=null, headers=[], subParams=[{paramsName=qq, paramsValue=951359056, paramsType=String, paramsDESC=qq}, {paramsName=page, paramsValue=1, paramsType=String, paramsDESC=页码}]}
        if (Objects.isNull(map)){
            throw new CustomException("取到数据为空，添加失败");
        }

        if (Objects.isNull(map.get("id"))){
            throw new CustomException("id不允许为空！");
        }

        String title = map.get("title")==null?null:map.get("title").toString();
        String url = map.get("url")==null?null:map.get("url").toString();
        String description = map.get("description")==null?null:map.get("description").toString();
        String method = map.get("method")==null?null:map.get("method").toString();
        String responseFormart = map.get("responseFormart")==null?null:map.get("responseFormart").toString();
        String requestBodyType = map.get("requestBodyType")==null?null:map.get("requestBodyType").toString();
        String headers = map.get("headers")==null?null:map.get("headers").toString();
        String responseDemo = map.get("responseDemo")==null?null:map.get("responseDemo").toString();
        String enabled = map.get("enabled")==null?null:map.get("enabled").toString();

        if (Strings.isBlank(title)){
            throw new CustomException("API名称不能为空！");
        }

        if (Strings.isBlank(url)){
            throw new CustomException("请求链接不能为空！");
        }

        if (Strings.isBlank(description)){
            throw new CustomException("API介绍不能为空！");
        }
        if (Strings.isBlank(method)){
            throw new CustomException("请求方式不能为空！");
        }
        if (Strings.isBlank(responseFormart)){
            throw new CustomException("响应格式不能为空！");
        }

        if (Strings.isBlank(requestBodyType)){
            throw new CustomException("提交内容类型不能为空！");
        }


        Apiinfo apiinfo = new Apiinfo();
        apiinfo.setId(Integer.valueOf(map.get("id").toString()));
        apiinfo.setTitle(title);
        apiinfo.setUrl(url);
        apiinfo.setDescription(description);
        apiinfo.setMethod(method);
        apiinfo.setResponseFormart(responseFormart);
        apiinfo.setRequestBodyType(requestBodyType);
        apiinfo.setRequestHeads(headers);
        apiinfo.setResponseDemo(responseDemo);
        apiinfo.setEnabled(enabled); // 启用
        if (RequestBodyTypeEnums.ParamsSubmit.getCode().equals(requestBodyType)){
            apiinfo.setRequestParams(map.get("subParams")==null?null:map.get("subParams").toString());
        }
        if (RequestBodyTypeEnums.JsonSubmit.getCode().equals(requestBodyType)){
            apiinfo.setRequestParams(map.get("requestBody")==null?null:map.get("requestBody").toString());
        }
        int i = baseMapper.updateById(apiinfo);

        return R.success("更新成功"+i + "条数据");
    }


    /**
     * 分页查询
     * @param pageDto
     * @return
     */
    @Override
    public R selectApiInfoByPage(PageDto pageDto) {
        System.out.println("pageDto = " + pageDto);

        Page<Apiinfo> page = new Page<>(pageDto.getCurrentPage(),pageDto.getSize());

        LambdaQueryWrapper<Apiinfo> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(Strings.isNotBlank(pageDto.getEnabled()),Apiinfo::getEnabled,pageDto.getEnabled())
                .and(Strings.isNotBlank(pageDto.getSearch()),w->w.like(Strings.isNotBlank(pageDto.getSearch()),Apiinfo::getTitle,pageDto.getSearch())
                        .or()
                        .like(Strings.isNotBlank(pageDto.getSearch()),Apiinfo::getUrl,pageDto.getSearch())
                        .or()
                        .like(Strings.isNotBlank(pageDto.getSearch()),Apiinfo::getDescription,pageDto.getSearch()));

        page = baseMapper.selectPage(page, wrapper);
        System.out.println("page = " + page.getRecords());
        PageDto dto = new PageDto(page.getTotal(), page.getSize(), page.getCurrent(), pageDto.getSearch(),pageDto.getEnabled(), page.getRecords());
        System.out.println("dto = " + dto);
        return R.success(dto);
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @Override
    public R deleteAPIByIds(List<Long> ids) {

        if (ids.size()<=0){
            throw new CustomException("至少选中一行数据");
        }

        int i = baseMapper.deleteBatchIds(ids);

        return R.success("成功删除" + i + "条数据！");
    }

    /**
     * 批量启用
     *
     * @param ids
     * @return
     */
    @Override
    public R enabledAPIByIds(List<Long> ids) {

        if (ids.size()<=0){
            throw new CustomException("至少选中一行数据");
        }

        LambdaUpdateWrapper<Apiinfo> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(Apiinfo::getEnabled,1)
                .in(Apiinfo::getId,ids);

        int i = baseMapper.update(null,wrapper);

        return R.success("成功启用" + i + "条数据！");
    }

    /**
     * 批量禁用
     *
     * @param ids
     * @return
     */
    @Override
    public R disabledAPIByIds(List<Long> ids) {

        if (ids.size()<=0){
            throw new CustomException("至少选中一行数据");
        }

        LambdaUpdateWrapper<Apiinfo> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(Apiinfo::getEnabled,0)
                .in(Apiinfo::getId,ids);

        int i = baseMapper.update(null,wrapper);

        return R.success("成功禁用" + i + "条数据！");
    }
}




